import java.util.Arrays;
import java.util.Scanner;


public class demo {
    // 合唱团▲▲▲▲▲▲(动态规划)
//有 n 个学生站成一排，每个学生有一个能力值，牛牛想从这 n 个学生中按照顺序选取 k 名学生，要求相邻两个学生的位置编号的差不超过 d，
//使得这 k 个学生的能力值的乘积最大，你能返回最大的乘积吗？
//输入描述:
    //保存的值可能很大 所以int类型不够 50^50这样
//每个输入包含 1 个测试用例。每个测试数据的第一行包含一个整数 n (1 <= n <= 50)，表示学生的个数，接下来的一行，包含 n 个整数，
// 按顺序表示每个学生的能力值 ai（-50 <= ai <= 50）。接下来的一行包含两个整数，k 和 d (1 <= k <= 10, 1 <= d <= 50)。
//输出描述:
//输出一行表示最大的乘积。
//输入
//3
//7 4 7
//2 50
//输出
//49


//【题目解析】：
//题目要求n各学生中选择k个，使这k个学生的能力值乘积最大。这是一个最优化的问题。另外，在优化过程
//中，提出了相邻两个学生的位置编号差不超过d的约束。解决的方法是采用动态规划
//【解题思路】：
//分析：该题目是一个动态规划的问题，那么我们首先要构造出状态转移方程。
//设maxVal[i][j]表示以第i个人为最后一个（前面共i个人，最后一个人必选），一共选取了j个人（包含i）时的最大乘积。
//同理，minVal[i][j]表示同样状态下的最小乘积（由于数据中存在负数，负数乘上某个极大的负数反而会变成正的极大值，因而需要同时记录最小值）。
//maxVal[i][j]很显然与maxVal[i][j-1]相关，可以理解为maxVal[i][j]由两部分组成，一部分是自身作为待选值，
//另一部分是maxVal[i][j-1]加上一个人后得到的值，然后取它们的极大值，由此可以得到状态转移方程如下：
//maxVal[i][j] = max(maxVal[i][j], max(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));
//minVal[i][j] = min(minVal[i][j], min(maxVal[c][j - 1] * a[i], minVal[c][j - 1] * a[i]));
//其中c的约束条件： i - d <= c <= i - 1
//初始状态：
//maxVal[i][1] = a[i];
//最后遍历maxVal[i][k]即可得到最大值。

    public static long getMaxCount(int[] arr, int n, int k, int d) {
        // 该题行用n来表示更易理解
        // 创建数组时 多一个空间
        // maxValue[1][1] 表示有一个元素 我们取一个
        // maxValue[2][1] 表示有一个元素 我们取一个(取的是他本身)
        // maxValue[2][1] 表示有两个元素 我们取两个.... 下面同理
        // 因为有负数情况 所以我们要保存该方程的最大最小值
        long[][] maxValue = new long[n+1][k+1];
        long[][] minValue = new long[n+1][k+1];


        // 接收maxVal[i][k]的最大值
        long max = 0;
        // 将下标为1的列 先赋值 意思 是 F(1,1)该元素本身必须取
        for (int i=1; i<=n; i++) {
            maxValue[i][1] = minValue[i][1] = arr[i-1];
        }

        for (int i=1; i<=n; i++) {
            for (int j=1; j<=k; j++) {
                // 约束条件 相邻同学间隔不超过d
                // 因为i-d可能为负数 因为第一个的元素在下标为1,1的位置 所以 m>=他们的最大值
                for (int m=i-1; m>=Math.max(1,i-d); m--) {
                    maxValue[i][j] = Math.max(maxValue[i][j],
                            Math.max(maxValue[m][j-1]*arr[i-1],
                                    minValue[m][j-1]*arr[i-1]));

                    minValue[i][j] = Math.min(minValue[i][j],
                            Math.min(minValue[m][j-1]*arr[i-1],
                                    maxValue[m][j-1]*arr[i-1]));
                }
            }
            max = Math.max(max, maxValue[i][k]);
        }
        return max;
    }

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            // 获取数据
            int n = sc.nextInt();
            int[] arr = new int[n];
            for (int i=0; i<n; i++) {
                arr[i] = sc.nextInt();
            }
            int k = sc.nextInt();
            int d = sc.nextInt();

            long count = getMaxCount(arr, n, k, d);
            System.out.println(count);
        }
    }









    // 马戏团▲▲▲▲▲▲(动态规划)
//搜狐员工小王最近利用假期在外地旅游，在某个小镇碰到一个马戏团表演，精彩的表演结束后发现团长正和大伙在帐篷前激烈讨论，小王打听了下了解到，
//马戏团正打算出一个新节目“最高罗汉塔”，即马戏团员叠罗汉表演。考虑到安全因素，要求叠罗汉过程中，站在某个人肩上的人应该既比自己矮又比自己瘦，
//或相等。 团长想要本次节目中的罗汉塔叠的最高，由于人数众多，正在头疼如何安排人员的问题。小王觉得这个问题很简单，
//于是统计了参与最高罗汉塔表演的所有团员的身高体重，并且很快找到叠最高罗汉塔的人员序列。 现在你手上也拿到了这样一份身高体重表
//请找出可以叠出的最高罗汉塔的高度，这份表中马戏团员依次编号为1到N。
//输入描述:
//首先一个正整数N，表示人员个数。


//    题目感觉模糊不清楚  理解最长升序子序列
//    答案是理解是这样:
//    要求:上面的人:   体重不相等，需要体重小，身高低或者相等
//                   体重相等，身高必须相等

//体重升序排列， 体重相同时，按身高降序排列 接下来就是按照身高数据进行最大升序子序列的长度
//注意：此题中，体重相同时，只有身高也相同才可以站在自己肩上，比自己矮是不能站在自己肩上的。所以
//如果想要排除体重相同时，只看身高相等的，不看身高矮的，所以身高降序排列
//求最大升序子序列的长度，采用动态规划

//状态F(i): 以第i个数据结尾的升序子序列的最大长度  包含该i个数据

//  j 表示 i之前的元素  F(j)表示 F(i)之前的结果
//    举个例子
//    数据是  95 100 80 100 70 101   求最长升序子序列
//F(0): 95 ---> 1
//F(1): 95 100 ---> 2
//F(2): 80 ---> 1
//F(3): 95 100 100 ---> 3
//F(4): 70 ---> 1
//F(5): 95 100 100 101 --> 4


//方程:F(i) = max(F(i), F(j) + 1)， 其中 j < i，其arr[j] <= arr[i]
//
//状态初始值：F(i) = 1      长度是一  表示为至少包含一个元素 所以F(0)=1
//
//返回值： max(F(i))       表示  i之前的j元素的加一的最大值


//之后N行，每行三个数，分别对应马戏团员编号，体重和身高。
//输出描述:
//正整数m，表示罗汉塔的高度。
//输入
//6
//1 65 100
//2 75 80
//3 80 100
//4 60 95
//5 82 101
//6 81 70
//输出
//4

    public static int getMaxLengthCount(Node[] node, int n) {
        // 保存从第一个数据 往后的升序子序列长度
        int[] maxLength = new int[n];
        // 保存最长的那条序列长度
        int maxCount = 0;
        for (int i=0 ; i<n; i++) {
            // 初始化长度为1 因为元素本身算一个单位长度
            maxLength[i] = 1;
        }
        // 先要进行排序
        Arrays.sort(node);

        // 主要代码
        for (int i=1; i<n; i++) {
            for (int j=0; j<i; j++) {
                // 我们已经按体重升序排列了 体重相同 升高降序排列
                if (node[j].height <= node[i].height) {
                    maxLength[i] = Math.max(maxLength[i], maxLength[j]+1);
                }
            }
            maxCount = Math.max(maxCount, maxLength[i]);
        }
        return maxCount;
    }
    public static void main1(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (sc.hasNextInt()) {
            int n = sc.nextInt();
            Node[] nodes = new Node[n];
            for (int i=0; i<n; i++) {
                // 去除每位团员的编号 (不需要)
                sc.nextInt();
                int weight = sc.nextInt();
                int height = sc.nextInt();
                nodes[i] = new Node(weight, height);
            }
            int count = getMaxLengthCount(nodes, n);
            System.out.println(count);
        }
    }
}




// 继承比较接口  因为我们要进行升高和体重的排序
class Node implements Comparable<Node> {
    int weight;
    int height;

    public Node (int weight, int height) {
        this.weight = weight;
        this.height = height;
    }

    // 因为继承Comparable<Node>接口   所以要重写compareTo(Node node)方法
    public int compareTo(Node node) {
        // 该题
        // 先体重升序
        // 如果体重相同升序 身高降序
        int ret = this.weight - node.weight;
        if (ret == 0) {
            ret = node.height - this.height;
        }
        return ret;
    }
}
